"""
KidsBuddy 1.0 用户验证器
提供用户数据的专门验证功能
"""

import re
from datetime import datetime, date
from typing import Optional, List, Dict, Any

from .validators import ValidationError, Validator


class AgeValidator(Validator[int]):
    """年龄验证器"""
    
    def __init__(self, min_age: int = 3, max_age: int = 18, error_message: Optional[str] = None):
        super().__init__(error_message)
        self.min_age = min_age
        self.max_age = max_age
    
    def validate(self, value: Any) -> int:
        if value is None:
            return None
        
        try:
            age = int(value)
        except (ValueError, TypeError):
            raise ValidationError(self.error_message or "年龄必须是数字")
        
        if age < self.min_age or age > self.max_age:
            raise ValidationError(
                self.error_message or f"年龄必须在{self.min_age}-{self.max_age}岁之间"
            )
        
        return age


class NameValidator(Validator[str]):
    """姓名验证器"""
    
    def __init__(self, min_length: int = 1, max_length: int = 50, error_message: Optional[str] = None):
        super().__init__(error_message)
        self.min_length = min_length
        self.max_length = max_length
    
    def validate(self, value: Any) -> str:
        if not isinstance(value, str):
            raise ValidationError(self.error_message or "姓名必须是字符串")
        
        name = value.strip()
        
        if len(name) < self.min_length:
            raise ValidationError(
                self.error_message or f"姓名长度不能少于{self.min_length}个字符"
            )
        
        if len(name) > self.max_length:
            raise ValidationError(
                self.error_message or f"姓名长度不能超过{self.max_length}个字符"
            )
        
        # 检查是否包含特殊字符（允许中文、英文、数字、空格、连字符）
        if not re.match(r'^[\u4e00-\u9fa5a-zA-Z0-9\s\-\.]+$', name):
            raise ValidationError(
                self.error_message or "姓名只能包含中文、英文、数字、空格、连字符和点号"
            )
        
        return name


class EmailValidator(Validator[str]):
    """邮箱验证器"""
    
    def validate(self, value: Any) -> str:
        if not isinstance(value, str):
            raise ValidationError(self.error_message or "邮箱必须是字符串")
        
        email = value.strip().lower()
        
        if not email:
            raise ValidationError(self.error_message or "邮箱不能为空")
        
        # 邮箱格式验证
        email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
        if not re.match(email_pattern, email):
            raise ValidationError(self.error_message or "邮箱格式不正确")
        
        # 检查邮箱长度
        if len(email) > 254:  # RFC 5321 标准
            raise ValidationError(self.error_message or "邮箱地址过长")
        
        return email


class PhoneValidator(Validator[str]):
    """手机号验证器"""
    
    def __init__(self, country_code: str = "CN", error_message: Optional[str] = None):
        super().__init__(error_message)
        self.country_code = country_code
    
    def validate(self, value: Any) -> str:
        if value is None:
            return None
        
        if not isinstance(value, str):
            raise ValidationError(self.error_message or "手机号必须是字符串")
        
        phone = re.sub(r'[\s\-\(\)]', '', value)  # 移除空格、连字符、括号
        
        if self.country_code == "CN":
            # 中国手机号验证
            if not re.match(r'^1[3-9]\d{9}$', phone):
                raise ValidationError(
                    self.error_message or "请输入有效的中国手机号（11位数字，以1开头）"
                )
        else:
            # 通用手机号验证（7-15位数字）
            if not re.match(r'^\d{7,15}$', phone):
                raise ValidationError(
                    self.error_message or "请输入有效的手机号（7-15位数字）"
                )
        
        return phone


class UserIdValidator(Validator[str]):
    """用户ID验证器"""
    
    def __init__(self, user_type: str, error_message: Optional[str] = None):
        super().__init__(error_message)
        self.user_type = user_type.lower()
    
    def validate(self, value: Any) -> str:
        if not isinstance(value, str):
            raise ValidationError(self.error_message or "用户ID必须是字符串")
        
        user_id = value.strip()
        
        if not user_id:
            raise ValidationError(self.error_message or "用户ID不能为空")
        
        # 检查ID格式：类型_8位十六进制
        expected_prefix = f"{self.user_type}_"
        if not user_id.startswith(expected_prefix):
            raise ValidationError(
                self.error_message or f"用户ID必须以'{expected_prefix}'开头"
            )
        
        # 检查ID长度和格式
        if len(user_id) != len(expected_prefix) + 8:
            raise ValidationError(
                self.error_message or f"用户ID格式不正确，应为'{expected_prefix}xxxxxxxx'"
            )
        
        # 检查后缀是否为十六进制
        suffix = user_id[len(expected_prefix):]
        if not re.match(r'^[a-f0-9]{8}$', suffix):
            raise ValidationError(
                self.error_message or "用户ID后缀必须是8位小写十六进制字符"
            )
        
        return user_id


class ScoreValidator(Validator[float]):
    """评分验证器"""
    
    def __init__(self, min_score: float = 0.0, max_score: float = 100.0, error_message: Optional[str] = None):
        super().__init__(error_message)
        self.min_score = min_score
        self.max_score = max_score
    
    def validate(self, value: Any) -> float:
        try:
            score = float(value)
        except (ValueError, TypeError):
            raise ValidationError(self.error_message or "评分必须是数字")
        
        if score < self.min_score or score > self.max_score:
            raise ValidationError(
                self.error_message or f"评分必须在{self.min_score}-{self.max_score}之间"
            )
        
        return score


class LevelValidator(Validator[int]):
    """等级验证器"""
    
    def __init__(self, min_level: int = 1, max_level: int = 10, error_message: Optional[str] = None):
        super().__init__(error_message)
        self.min_level = min_level
        self.max_level = max_level
    
    def validate(self, value: Any) -> int:
        try:
            level = int(value)
        except (ValueError, TypeError):
            raise ValidationError(self.error_message or "等级必须是整数")
        
        if level < self.min_level or level > self.max_level:
            raise ValidationError(
                self.error_message or f"等级必须在{self.min_level}-{self.max_level}之间"
            )
        
        return level


# 便捷验证函数

def validate_age(age: Any, min_age: int = 3, max_age: int = 18) -> int:
    """验证年龄"""
    validator = AgeValidator(min_age, max_age)
    return validator.validate(age)


def validate_name(name: Any, min_length: int = 1, max_length: int = 50) -> str:
    """验证姓名"""
    validator = NameValidator(min_length, max_length)
    return validator.validate(name)


def validate_email(email: Any) -> str:
    """验证邮箱"""
    validator = EmailValidator()
    return validator.validate(email)


def validate_phone(phone: Any, country_code: str = "CN") -> str:
    """验证手机号"""
    validator = PhoneValidator(country_code)
    return validator.validate(phone)


def validate_child_id(user_id: Any) -> str:
    """验证儿童用户ID"""
    validator = UserIdValidator("child")
    return validator.validate(user_id)


def validate_parent_id(user_id: Any) -> str:
    """验证家长用户ID"""
    validator = UserIdValidator("parent")
    return validator.validate(user_id)


def validate_srl_score(score: Any) -> float:
    """验证SRL评分"""
    validator = ScoreValidator(0.0, 100.0)
    return validator.validate(score)


def validate_task_level(level: Any) -> int:
    """验证任务等级"""
    validator = LevelValidator(1, 10)
    return validator.validate(level)


def validate_child_data(data: Dict[str, Any]) -> Dict[str, Any]:
    """验证儿童用户完整数据"""
    validated_data = {}
    
    # 必需字段验证
    validated_data['name'] = validate_name(data.get('name', ''))
    
    # 可选字段验证
    if 'age' in data and data['age'] is not None:
        validated_data['age'] = validate_age(data['age'])
    
    if 'id' in data:
        validated_data['id'] = validate_child_id(data['id'])
    
    # SRL评分验证
    srl_fields = [
        'goal_setting_score', 'planning_score', 'monitoring_score',
        'evaluation_score', 'reflection_score', 'strategy_use_score',
        'motivation_regulation_score'
    ]
    
    for field in srl_fields:
        if field in data:
            validated_data[field] = validate_srl_score(data[field])
    
    # 任务等级验证
    task_fields = [
        'reading_aloud_level', 'reading_comprehension_level',
        'memorization_level', 'dictation_level', 'writing_level', 'copying_level'
    ]
    
    for field in task_fields:
        if field in data:
            validated_data[field] = validate_task_level(data[field])
    
    return validated_data


def validate_parent_data(data: Dict[str, Any]) -> Dict[str, Any]:
    """验证家长用户完整数据"""
    validated_data = {}
    
    # 必需字段验证
    validated_data['name'] = validate_name(data.get('name', ''))
    validated_data['email'] = validate_email(data.get('email', ''))
    
    # 可选字段验证
    if 'phone' in data and data['phone']:
        validated_data['phone'] = validate_phone(data['phone'])
    
    if 'id' in data:
        validated_data['id'] = validate_parent_id(data['id'])
    
    return validated_data
